#include "JSValueWrapper.h"

namespace AwesomiumDotNet
{
	typedef void (*BeginLoadingCallback) (const std::string& url, const std::wstring& frameName, int statusCode, const std::wstring& mimeType);
	typedef void (*BeginNavigationCallback) (const std::string& url, const std::wstring& frameName);
	typedef void (*CallbackCallback) (const std::string& name, const Awesomium::JSArguments& args);
	typedef void (*ChangeCursorCallback) (const HCURSOR& cursor);
	typedef void (*ChangeKeyboardFocusCallback) (bool isFocused);
	typedef void (*ChangeTargetUrlCallback) (const std::string& url);
	typedef void (*ChangeTooltipCallback) (const std::wstring& tooltip);
	typedef void (*FinishLoadingCallback) ();
	typedef void (*ReceiveTitleCallback) (const std::wstring& title, const std::wstring& frameName);

	class MyWebViewListener : public Awesomium::WebViewListener
	{
		BeginLoadingCallback cb_onBeginLoading;
		BeginNavigationCallback cb_onBeginNavigation;
		CallbackCallback cb_onCallback;
		ChangeCursorCallback cb_onChangeCursor;
		ChangeKeyboardFocusCallback cb_onChangeKeyboardFocus;
		ChangeTargetUrlCallback cb_onChangeTargetURL;
		ChangeTooltipCallback cb_onChangeTooltip;
		FinishLoadingCallback cb_onFinishLoading;
		ReceiveTitleCallback cb_onReceiveTitle;

	public:
		void set_onBeginLoading(BeginLoadingCallback ptr2F) {
			cb_onBeginLoading = ptr2F; }
		void set_onBeginNavigation(BeginNavigationCallback ptr2F) {
			cb_onBeginNavigation = ptr2F; }
		void set_onCallback(CallbackCallback ptr2F) {
			cb_onCallback = ptr2F; }
		void set_onChangeCursor(ChangeCursorCallback ptr2F) {
			cb_onChangeCursor = ptr2F; }
		void set_onChangeKeyboardFocus(ChangeKeyboardFocusCallback ptr2F) {
			cb_onChangeKeyboardFocus = ptr2F; }
		void set_onChangeTargetURL(ChangeTargetUrlCallback ptr2F) {
			cb_onChangeTargetURL = ptr2F; }
		void set_onFinishLoading(FinishLoadingCallback ptr2F) {
			cb_onFinishLoading = ptr2F; }
		void set_onReceiveTitle(ReceiveTitleCallback ptr2F) {
			cb_onReceiveTitle = ptr2F; }
		void set_onChangeTooltip(ChangeTooltipCallback ptr2F) {
			cb_onChangeTooltip = ptr2F; }

	public:
		MyWebViewListener()
		{
		}

		void onBeginLoading(const std::string& url, const std::wstring& frameName, int statusCode, const std::wstring& mimeType)
		{
			cb_onBeginLoading(url, frameName, statusCode, mimeType);
		}

		void onCallback(const std::string& name, const Awesomium::JSArguments& args)
		{
			cb_onCallback(name, args);
		}

		void onBeginNavigation(const std::string& url, const std::wstring& frameName)
		{
			cb_onBeginNavigation(url, frameName);
		}

		void onChangeCursor(const HCURSOR& cursor)
		{
			cb_onChangeCursor(cursor);
		}

		void onChangeKeyboardFocus(bool isFocused)
		{
			cb_onChangeKeyboardFocus(isFocused);
		}

		void onChangeTargetURL(const std::string& url)
		{
			cb_onChangeTargetURL(url);
		}

		void onChangeTooltip(const std::wstring& tooltip)
		{
			cb_onChangeTooltip(tooltip);
		}

		void onFinishLoading()
		{
			cb_onFinishLoading();
		}

		void onReceiveTitle(const std::wstring& title, const std::wstring& frameName)
		{
			cb_onReceiveTitle(title, frameName);
		}
	};

	namespace Args
	{
		public ref class BeginLoadingEventArgs : System::EventArgs
		{
		public:
			property String^ Url;
			property String^ FrameName;
			property int StatusCode;
			property String^ MimeType;
		public:
			BeginLoadingEventArgs(String^ url, String^ frameName, int statusCode, String^ mimeType) {
				this->Url = url;
				this->FrameName = frameName;
				this->StatusCode = statusCode;
				this->MimeType = mimeType;
			}
		};

		public ref class BeginNavigationEventArgs : System::EventArgs
		{
		public:
			property String^ Url;
			property String^ FrameName;
		public:
			BeginNavigationEventArgs(String^ url, String^ frameName) {
				this->Url = url;
				this->FrameName = frameName;
			}
		};

		public ref class CallbackEventArgs : System::EventArgs
		{
		public:
			property String^ Name;
			const List<JSValue^>^ args;
		public:
			CallbackEventArgs(String^ name, const List<JSValue^>^ args) {
				this->Name = name;
				this->args = args;
			}
		};

		public ref class ChangeCursorEventArgs : System::EventArgs
		{
		public:
			// Cursor cursor;
		public:
			ChangeCursorEventArgs() {
				// this->cursor = cursor;
			}
		};

		public ref class ChangeKeyboardFocusEventArgs : System::EventArgs
		{
		public:
			property bool IsFocused;
		public:
			ChangeKeyboardFocusEventArgs(bool isFocused) {
				this->IsFocused = isFocused;
			}
		};

		public ref class ChangeTargetUrlEventArgs : System::EventArgs
		{
		public:
			property String^ Url;
		public:
			ChangeTargetUrlEventArgs(String^ url) {
				this->Url = url;
			}
		};

		public ref class ChangeTooltipEventArgs : System::EventArgs
		{
		public:
			property String^ Tooltip;
		public:
			ChangeTooltipEventArgs(String^ tooltip) {
				this->Tooltip = tooltip;
			}
		};

		public ref class FinishLoadingEventArgs : System::EventArgs
		{
		};

		public ref class ReceiveTitleEventArgs : System::EventArgs
		{
		public:
			property String^ Title;
			property String^ FrameName;
		public:
			ReceiveTitleEventArgs(String^ title, String^ frameName) {
				this->Title = title;
				this->FrameName = frameName;
			}
		};
	}
}
